package com.ruyiadmin.springboot.controller.system;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruyiadmin.springboot.common.annotations.system.Log;
import com.ruyiadmin.springboot.common.annotations.system.Permission;
import com.ruyiadmin.springboot.common.classes.system.FileInfo;
import com.ruyiadmin.springboot.common.core.business.enums.OperationType;
import com.ruyiadmin.springboot.common.core.system.entities.ActionResult;
import com.ruyiadmin.springboot.common.core.system.entities.QueryCondition;
import com.ruyiadmin.springboot.common.core.system.entities.QueryItem;
import com.ruyiadmin.springboot.common.core.system.entities.QueryResult;
import com.ruyiadmin.springboot.common.core.system.enums.DataType;
import com.ruyiadmin.springboot.common.core.system.enums.QueryMethod;
import com.ruyiadmin.springboot.common.exceptions.RuYiAdminCustomException;
import com.ruyiadmin.springboot.common.utils.core.RuYiFileUtil;
import com.ruyiadmin.springboot.domain.entity.system.SysAttachment;
import com.ruyiadmin.springboot.service.iservices.system.ISysAttachmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 系统附件表 前端控制器
 * </p>
 *
 * @author RuYiAdmin
 * @since 2022-07-11
 */
@RestController
@RequestMapping("/AttachmentManagement")
@Api(tags = "系统附件管理服务")
@RequiredArgsConstructor
public class SysAttachmentController {

    //region 服务私有属性

    private final ISysAttachmentService attachmentService;

    //endregion

    //region 上传业务附件

    @PostMapping("/UploadAttachments")
    @ApiOperation(value = "上传业务附件")
    @Log(OperationType = OperationType.UploadFile)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ActionResult uploadAttachments(@RequestParam("file") MultipartFile[] files, String businessId)
            throws IOException {
        List<SysAttachment> attachments = new ArrayList<>();
        for (MultipartFile file : files) {
            String id = UUID.randomUUID().toString();
            FileInfo fileInfo = RuYiFileUtil.getFileInfo(file);
            SysAttachment attachment = new SysAttachment();
            attachment.setId(id);
            attachment.setFileName(file.getOriginalFilename());
            attachment.setFileSize(fileInfo.getSize());
            attachment.setRemark(fileInfo.getRemark());
            attachment.setFilePath(RuYiFileUtil.saveBusinessAttachment(file, id));
            attachment.setBusinessId(businessId);
            attachments.add(attachment);
        }
        this.attachmentService.saveBatch(attachments);
        return ActionResult.ok();
    }

    //endregion

    //region 获取业务附件

    @GetMapping("/GetAttachments/{businessId}")
    @ApiOperation(value = "获取业务附件")
    @Log(OperationType = OperationType.QueryList)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public QueryResult<SysAttachment> getAttachments(@PathVariable("businessId") String businessId) {
        QueryCondition queryCondition = new QueryCondition();
        queryCondition.setQueryItems(new ArrayList<>());
        queryCondition.getQueryItems().add(
                new QueryItem("BUSINESS_ID", DataType.Guid, QueryMethod.Equal, businessId)
        );
        QueryWrapper<SysAttachment> wrapper = new QueryWrapper<>();
        queryCondition.getQueryWrapper(wrapper);
        List<SysAttachment> list = this.attachmentService.list(wrapper);
        return QueryResult.success(list.size(), list);
    }

    //endregion

    //region 下载业务附件

    @GetMapping("/DownloadAttachment/{attachmentId}")
    @ApiOperation(value = "下载业务附件")
    @Log(OperationType = OperationType.DownloadFile)
    public void downloadAttachment(@PathVariable("attachmentId") String attachmentId,
                                   HttpServletResponse response) {
        FileInputStream fis = null;
        ServletOutputStream sos = null;
        try {
            SysAttachment attachment = this.attachmentService.getById(attachmentId);
            String fileName = attachment.getFileName();
            String filePath = attachment.getFilePath();
            //设置响应头
            response.setHeader("Content-Disposition", "attachment;filename="
                    + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
            fis = new FileInputStream(FileUtil.file(filePath));
            sos = response.getOutputStream();
            IOUtils.copy(fis, sos);
        } catch (Exception e) {
            throw new RuYiAdminCustomException("download error");
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (sos != null) {
                    sos.flush();
                    sos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    //endregion

    //region 删除业务附件

    @DeleteMapping("/DeleteAttachment/{attachmentIds}")
    @ApiOperation(value = "删除业务附件")
    @Log(OperationType = OperationType.DeleteEntity)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ActionResult deleteAttachment(@PathVariable("attachmentIds") String attachmentIds) {
        List<String> array = Arrays.asList(attachmentIds.split(","));
        //删除业务文件
        array.forEach(item -> {
            SysAttachment attachment = this.attachmentService.getById(item);
            FileUtil.del(attachment.getFilePath());
        });
        //删除数据
        this.attachmentService.removeByIds(array);
        return ActionResult.ok();
    }

    //endregion

    //region 系统文件统计

    @GetMapping("/GetSysFileStatisticalInfo")
    @ApiOperation(value = "系统文件统计")
    @Log(OperationType = OperationType.QueryEntity)
    @Permission(permission = "attachment:query:list")
    public ActionResult querySysFileStatisticalInfo() {
        return this.attachmentService.querySysFileStatisticalInfo();
    }

    //endregion

}
